/*
 * Create Date 2006-5-19
 */
package afss.freesky.data.conn;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.log4j.Logger;

/**
 * Title: FreeSky Common Java Library <br>
 * Description: FreeSky Common Java Library <br>
 * Copyright: Copyright (c) 2005~2009 www.afss.cn <br>
 * Company: Amei's FreeSky Studio <br>
 * 
 * @author <b>Jacky Chou</b> (AFSS [Amei's FreeSky Studio])
 * @version 1.2.1, 2008-08-05, Clean and optimize the source code. <br>
 *          1.2.0, 2008-02-23, Upgrade freesky.jar to 1.2.0 with Struts 2 <br>
 *          1.0.0, 2006-05-30, Initial Version
 */
public abstract class DBConnBean implements Serializable, IDBConn {
	private static final long serialVersionUID = 7187870319928557682L;

	/**
	 * Log4J Logger for this class
	 */
	static final Logger logger = Logger.getLogger(DBConnBean.class);

	protected Connection conn = null;
	protected Statement stmt = null;
	private boolean unitOfWork = false;

	public DBConnBean() {
		getConnection();
	}

	public static DBConnBean instance(String db) {
		DBConnBean bean = null;
		if (db.equalsIgnoreCase("Access")) {
			bean = new DBAccessBean();
		} else if (db.equalsIgnoreCase("Oracle")) {
			bean = new DBOracleBean();
		} else if (db.equalsIgnoreCase("DB2")) {
			bean = new DBDb2Bean();
		} else if (db.equalsIgnoreCase("MySQL")) {
			bean = new DBMySQLBean();
		} else if (db.equalsIgnoreCase("SqlServer2k")) {
			bean = new DBSql2kBean();
		} else if (db.equalsIgnoreCase("SqlServer2k5")) {
			bean = new DBSql2k5Bean();
		} else
			bean = new DBAccessBean();
		return bean;
	}

	public abstract void getConnection();

	public Connection getDBConnection() {
		if (conn == null) {
			logger.error("ConnectDB.getDBConnection()");
		}
		return conn;
	}

	public ResultSet executeQuery(String sqlStr) throws SQLException {
		ResultSet rs = null;

		if (conn == null) {
			getConnection();
		}
		try {
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sqlStr);
			return rs;
		} catch (SQLException e) {
			logger.error("ִConnectDB.executeQuery: ".concat(e.getMessage()));
			throw e;
		}
	}

	public PreparedStatement prepareStatement(String sqlStr) throws SQLException {
		PreparedStatement pstmt = null;
		if (conn == null) {
			return pstmt;
		}
		pstmt = conn.prepareStatement(sqlStr);
		return pstmt;
	}

	public int executeUpdate(String sqlStr) throws SQLException {
		int resultNum;
		try {
			stmt = conn.createStatement();
			resultNum = stmt.executeUpdate(sqlStr);
			stmt.close();
			return resultNum;
		} catch (SQLException ex) {
			logger.error("ConnectDB.executeUpdate: ".concat(ex.getMessage()));
			throw ex;
		}
	}

	public void beginTran(boolean supportTran) throws SQLException {
		unitOfWork = supportTran;
		try {
			if (supportTran) {
				conn.setAutoCommit(false);
			} else {
				conn.setAutoCommit(true);
			}
		} catch (SQLException e) {
			logger.error("beginTran(boolean)", e);
			throw e;
		}
	}

	public void commitTran() throws SQLException {
		if (unitOfWork) {
			try {
				conn.commit();
			} catch (SQLException e) {
				rollBackTran();
				logger.error("ConnectDB.commitTran:".concat(e.getMessage()));
				throw e;
			}
		}
		close();
	}

	public boolean rollBackTran() throws SQLException {
		try {
			conn.rollback();
			close();
			return true;
		} catch (SQLException e) {
			logger.error("ConnectDB.rollBackTran:".concat(e.getMessage()));
			throw e;
		}
	}

	public void close() {
		try {
			if (conn != null && !conn.isClosed()) {
				conn.close();
			}
		} catch (SQLException e) {
			logger.error("ConnectDB.close:".concat(e.getMessage()));
		}
	}

	public void closeResultSet(ResultSet rs) {
		try {
			if (rs != null) {
				rs.close();
			}
		} catch (SQLException e) {
			logger.error("ConnectDB.closeResultSet:".concat(e.getMessage()));
		}
	}

	public void closeStatement() {
		try {
			if (stmt != null) {
				stmt.close();
			}
		} catch (SQLException e) {
			logger.error("ConnectDB.closeStatement:".concat(e.getMessage()));
		}
	}

	public int getTotal(String sql) {
		int ret = 0;
		if (sql == null) {
			return ret;
		}
		ResultSet rs = null;
		try {
			rs = this.executeQuery(sql);
			if (rs.next()) {
				ret = rs.getInt(1);
			}
			rs.close();
		} catch (SQLException sqle) {
			logger.error("getTotal(String sql)".concat(sqle.getMessage()));
			if (rs != null) {
				this.closeResultSet(rs);
			}
		}
		return ret;
	}
}
